package service

import (
	"encoding/json"
	"fmt"
	"math/rand"
	"time"

	"github.com/aliyun/alibaba-cloud-sdk-go/services/dysmsapi"
	"github.com/google/logger"
	"github.com/topaz-h/gin-web/dao"
	"github.com/topaz-h/gin-web/model"
	"github.com/topaz-h/gin-web/params"
	"github.com/topaz-h/gin-web/tools"
)

// AuthService 结构体
type AuthService struct {
}

// SendSmsCode 实际发送验证码的服务层函数
func (a *AuthService) SendSmsCode(phone string) bool {
	// 1.后端生成一个4位纯数字验证码
	code := fmt.Sprintf("%04v", rand.New(rand.NewSource(time.Now().UnixNano())).Int31n(10000))

	// 2.调用[阿里云SDK](https://api.aliyun.com/?spm=5176.12207334.0.0.54d71cbe3NE29f#/?product=Dysmsapi&version=2017-05-25&api=SendSms&tab=DEMO&lang=GO)
	// 通过`示例代码`和`查看文档`-完成发送
	/* sms格式
	sms: {
		"sign_name": "线上餐厅",
		"template_code": "SMS_176525619",
		"access_key_id": "???",
		"access_secret": "???",
		"region_id": "cn-hangzhou"
	}
	*/
	smsConfig := tools.GetConfig().Sms
	client, err := dysmsapi.NewClientWithAccessKey(smsConfig.RegionId, smsConfig.AccessKeyId, smsConfig.AccessSecret)
	if err != nil {
		logger.Error(err.Error())
		return false
	}
	// 构造一个请求对象
	request := dysmsapi.CreateSendSmsRequest()
	// 设置Scheme等参数
	request.Scheme = "https"
	request.SignName = smsConfig.SignName
	request.TemplateCode = smsConfig.TemplateCode
	request.PhoneNumbers = phone
	// 替换成后端生成的4位数字验证码
	par, err := json.Marshal(map[string]interface{}{
		"code": code,
	})
	if err != nil {
		logger.Error(err.Error())
		return false
	}
	request.TemplateParam = string(par)

	// 3.接收返回结果，并判断发送状态-返回给controller
	/* response格式
	response: {
		"Message": "OK",
		"RequestId": "873043ac-bcda-44db-9052-2e204c6ed20f",
		"BizId": "607300000000000000^0",
		"Recommend": "",
		"HostId": "",
		"Code": "OK"
	}
	*/
	response, err := client.SendSms(request)
	// fmt.Println(code) // 2573
	// fmt.Println(response.Code) //响应体和response结构体对象
	if err != nil {
		logger.Error(err.Error())
		return false
	}
	if response.Code == "OK" { // 插入多条匹配最后时间的
		// if response.Code == "MissingAccessKeyId" {
		// if true {
		// 请求状态码: 返回OK代表请求成功(仅此一种成功响应)
		// TODO：验证持久化，等待客户端验证
		smsCode := model.SmsCode{
			Phone: phone,
			Code:  code,
			BizId: response.BizId,
			// BizId:      "12113212",
			CreateTime: time.Now().Unix(),
		}
		// fmt.Println(smsCode)
		memberDao := dao.MemberDao{tools.DbEngine}
		result := memberDao.InsertSmsCode(smsCode)
		// fmt.Println(result)
		return result > 0
	}
	return false
}

// LoginSms 短信验证码登录服务层函数
func (a *AuthService) LoginSms(loginSmsParams params.LoginSmsParams) *model.Member {
	// 验证手机和验证码是否已匹配
	m := dao.MemberDao{tools.DbEngine}
	// TODO: 插入多条匹配最后时间的; 但是此处仅校验是否存在
	sms := m.ValidateLoginSms(loginSmsParams.Phone, loginSmsParams.Code)
	if sms.Id == 0 {
		// 没有查询到已匹配的短信验证码，结构体的字段Id默认值为0
		return nil
	}
	// 查询是否有此用户
	member := m.QueryByPhoneOfMember(loginSmsParams.Phone)
	if member.Id != 0 {
		// 查询到用户，结构体的字段不为Id默认值为0
		return member
	}
	// 没有查询到就注册新用户
	user := model.Member{}
	user.UserName = loginSmsParams.Phone
	user.Mobile = loginSmsParams.Phone
	user.RegisterTime = time.Now().Unix()
	user.Id = m.InsertMember(user)
	return &user
}

// LoginCaptcha 图形验证码登录时验证用户表服务层函数
func (a *AuthService) LoginCaptcha(username, password string) *model.Member {
	// 得到密文
	var encodePwd string = tools.EncoderSha256(password)
	// 验证手机和密码是否已匹配
	m := dao.MemberDao{tools.DbEngine}
	member := m.QueryByUserNameOfMember(username, encodePwd)
	if member.Id != 0 {
		// 查询到，结构体的字段Id默认值为0
		return member
	}
	// 没有查询到就注册新用户
	user := model.Member{}
	user.UserName = username
	user.Password = encodePwd
	user.RegisterTime = time.Now().Unix()
	// 注册/插入
	user.Id = m.InsertMember(user)
	return &user
}

// UploadAvatar 上传头像到用户表服务层函数
func (a *AuthService) UploadAvatar(id int64, avatar string) string {
	m := dao.MemberDao{tools.DbEngine}
	result := m.UpdateAvatar(id, avatar)
	if result == 0 {
		return ""
	}
	return avatar
}
